<template>
  <div class="hauner gas-table__box">
    <el-table
      ref="tableRef"
      class="mt20"
      :size="size"
      :border="border"
      :data="tData"
      :stripe="stripe"
      :header-cell-style="headerCellStyle"
      :header-cell-class-name="headerCellClassName"
      :highlight-current-row="highlightCurrentRow"
      :height="height"
      :span-method="spanMethod"
      :current-row-key="currentRowKey"
      :row-key="rowKey"
      :empty-text="emptyText"
      @select="select"
      @select-all="selectAllEvent"
      @selection-change="selectionChange"
      @cell-mouse-enter='cellMouseEnter'
      @cell-click="onCellClick"
      @row-click="onRowClick"
      @sort-change="e => $emit('sort-change', e)"
    > 
      <template #empty>
        <slot name="empty">{{ emptyText }}</slot>
      </template>
      <template v-for="(col, index) in tableHead">
        <el-table-column
          v-if="col.type == 'radio'"
          :key="index + (col.label ? col.label : col.type)"
          label="选择"
          width="55"
          :selectable="col.selectable"
        >
          <template #default="{ row, $index }">
            <el-radio
              v-model="radioSelect"
              :disabled="!col.selectable(row)"
              :style="`text-algin:center`"
              :index="$index"
              :label="row"
              >&nbsp;</el-radio
            >
          </template>
        </el-table-column>
        <el-table-column  v-else 
          v-show="!col.hidden"       
          :key="col.prop"
          :prop="col.prop"
          :label="col.label"
          :align="col.align"
          :width="col.width"
          :type="col.type"
          :fixed="col.fixed"
          :min-width="`${col.label?.length * 14 + 24}px`"
          :show-overflow-tooltip="!col.slot"
        >
          <template v-if="col.slot" #default="{row, $index}">
            <slot :name="col.slot" :row="row" :col="col" :ind="$index"></slot>
          </template>
          <template v-else-if="!col.type" #default="{row}">
            <span :class="col.classFn ? col.classFn(row) : ''">{{ col.filter ? col.filter(row) : row[col.prop] ?? defaultValue}}</span>
          </template>
          <template #header>            
            <slot :name="col.headSlot" :col="col">{{ col.label }}</slot>
          </template>
          <el-table-column
            v-for="chi in col.children"
            v-show="!chi.hidden"       
            :key="chi.prop"            
            :prop="chi.prop"
            :label="chi.label"
            :align="chi.align"
            :width="chi.width"
            :type="chi.type"
            :fixed="chi.fixed"
            :min-width="`${chi.label?.length * 14 + 24}px`"
            :show-overflow-tooltip="!chi.slot"
          >
            <template v-if="chi.slot" #default="obj">
              <slot :name="chi.slot" :obj="obj"></slot>
            </template>
            <template v-if="chi.headSlot" #header>
              <slot :name="chi.headSlot" :col="chi" >{{ chi.label }}</slot>
            </template>
          </el-table-column>
        </el-table-column>
      </template>
    </el-table>
  </div>
</template>
<script>
export default { name: 'HaTable' }
</script>
<script setup>
import { sleep } from '../../utils'
import { nextTick, ref, watch } from 'vue'

const prop = defineProps({
  emptyText: { type: String, default: '暂无数据' },
  currentRowKey: { type: String, default: '7' },
  rowKey: { type: String, default: 'id' },
  highlightCurrentRow: { type: Boolean, default: true },
  clickTriggerSelection: { type: Boolean, default: true },
  head: { type: Array, default: () => [] },
  height: { type: [String, Number], default: `calc(100% - 1px)` },
  tableData: { type: Array, default: () => [] },
  stripe: { type: Boolean, default: false },
  border: { type: Boolean, default: false },
  headerCellStyle: { type: [Function, Object], default: () => ({}) },
  spanMethod: { type: Function, default: () => {} },
  headerCellClassName: { type: String, default: 'gary-header__table' },
  defaultValue: { type: [String, Number], default: ' ' },
  radio: { type: Boolean, default: false },
  radioModel: {type: Object, default: null},
  size: { type: String, default: 'medium' },
})
const tableRef = ref(null)
const radioSelect = ref(null)
const tableHead = ref(prop.head)
const tData = ref(prop.tableData)
watch(() => prop.head, newVal => tableHead.value = newVal)
watch(() => prop.radioModel, newVal => radioSelect.value = newVal)
watch(radioSelect, row => select([row], row))
watch(() => prop.tableData, () => {
  tData.value = prop.tableData
  doLayout()
}, {deep: true})

function selectAll() {
  nextTick( () => { 
    tableRef.value?.toggleAllSelection()
    doLayout()
  })
}

const emit = defineEmits(['cell-click', 'row-click', 'selection-change', 'select', 'select-all', 'cell-mouse-enter'])
function onCellClick(row, column, cell, event) {
  emit('cell-click', row, column, cell, event )
}

function onRowClick(row, column, event) {
  if(prop.clickTriggerSelection){
    radioSelect.value = row
  }
  emit('row-click',  row, column, event )
}

function selectionChange(selection) {
  emit('selection-change', selection)
}

function select(selection, row) {
  emit('select', selection, row )
}

function selectAllEvent(e) {
  emit('select-all', e)
}

function cellMouseEnter(	row, column, cell, event) {
  emit('cell-mouse-enter', 	row, column, cell, event) 
}

async function doLayout(){
  while(true) {
    if(tableRef.value){
      nextTick( () => tableRef.value?.doLayout() )          
      return
    }
    await sleep(100)
  }
}
</script>
<style lang="scss" scoped>
</style>
